home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / c / c-tools-.000 / c-tools- / c-tools-0.4 / hash.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-13  |  4.3 KB  |  210 lines

  1. /* hash.c -- General hash table handling functions.
  2.    Copyright (C) 1995 Sandro Sigala - <sansig@freenet.hut.fi> */
  3.  
  4. /* $Id: hash.c,v 1.5 1995/08/08 11:52:03 sandro Exp $ */
  5.  
  6. /* This program is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2 of the License, or
  9.    (at your option) any later version.
  10.  
  11.    This program is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with this program; if not, write to the Free Software
  18.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20.  
  21. /*
  22.  *  to do:
  23.  *   - table must be allocated on hash_table_build(size) call with
  24.  *     an user preferred size.
  25.  *   - an user made hashing function can be specified by the user.
  26.  *
  27.  *  return codes:
  28.  *    HASH_OK: all ok
  29.  *    HASH_INVALID_PARAMETER: invalid parameter(s)
  30.  *    HASH_NOT_FOUND: key not found in hash table
  31.  *    HASH_ALREADY_EXIST: key already exists in hash table
  32.  */
  33.  
  34. #include <assert.h>
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <string.h>
  38.  
  39. #include "hash.h"
  40. #include "misc.h"
  41.  
  42. static struct bucket *
  43. build_bucket (char *key)
  44. {
  45.     struct bucket *ptr;
  46.  
  47.     ptr = (struct bucket *) xmalloc (sizeof (struct bucket));
  48.  
  49.     ptr->key = (char *) xmalloc (strlen (key) + 1);
  50.     strcpy (ptr->key, key);
  51.  
  52.     ptr->data = NULL;
  53.     ptr->next = NULL;
  54.  
  55.     return ptr;
  56. }
  57.  
  58. static void
  59. free_bucket (struct bucket *ptr)
  60. {
  61.     assert (ptr != NULL);
  62.  
  63.     if (ptr->key != NULL)
  64.     free (ptr->key);
  65.     if (ptr->data != NULL)
  66.     free (ptr->data);
  67.  
  68.     free (ptr);
  69. }
  70.  
  71. struct hash_table *
  72. hash_table_build (void)
  73. {
  74.     struct hash_table *ptr;
  75.     int i;
  76.  
  77.     ptr = (struct hash_table *) xmalloc (sizeof (struct hash_table));
  78.  
  79.     for (i = 0; i < HASH_TABLE_SIZE; i++)
  80.     ptr->table[i] = NULL;
  81.  
  82.     return ptr;
  83. }
  84.  
  85. int
  86. hash_table_free (struct hash_table *table)
  87. {
  88.     struct bucket *bucket, *next;
  89.     int i;
  90.  
  91.     if (table == NULL)
  92.     return HASH_INVALID_PARAMETER;
  93.  
  94.     for (i = 0; i < HASH_TABLE_SIZE; i++)
  95.     {
  96.     bucket = table->table[i];
  97.  
  98.     while (bucket != NULL)
  99.     {
  100.         next = bucket->next;
  101.         free_bucket (bucket);
  102.         bucket = next;
  103.     }
  104.     }
  105.  
  106.     free (table);
  107.  
  108.     return HASH_OK;
  109. }
  110.  
  111. static unsigned int
  112. hash_table_hash (char *key)
  113. {
  114.     unsigned int hash = 0;
  115.     char *p;
  116.  
  117.     for (p = key; *p != '\0'; p++)
  118.     hash = hash * 58 + *p;
  119.  
  120.     return (hash % HASH_TABLE_SIZE);
  121. }
  122.  
  123. int
  124. hash_table_add (struct hash_table *table, char *key)
  125. {
  126.     struct bucket *bucket;
  127.     int hash;
  128.  
  129.     if (table == NULL || key == NULL)
  130.     return HASH_INVALID_PARAMETER;
  131.  
  132.     if (hash_table_lookup (table, key) == HASH_OK)
  133.     return HASH_ALREADY_EXIST;
  134.  
  135.     hash = hash_table_hash (key);
  136.  
  137.     if (table->table[hash] == NULL)
  138.     table->table[hash] = build_bucket (key);
  139.     else
  140.     {
  141.     bucket = table->table[hash];
  142.  
  143.     while (bucket->next != NULL)
  144.         bucket = bucket->next;
  145.  
  146.     bucket->next = build_bucket (key);
  147.     }
  148.  
  149.     return HASH_OK;
  150. }
  151.  
  152. int
  153. hash_table_lookup (struct hash_table *table, char *key)
  154. {
  155.     struct bucket *bucket;
  156.     int hash;
  157.  
  158.     if (table == NULL || key == NULL)
  159.     return HASH_INVALID_PARAMETER;
  160.  
  161.     hash = hash_table_hash (key);
  162.  
  163.     for (bucket = table->table[hash]; bucket != NULL; bucket = bucket->next)
  164.     if (strcmp (bucket->key, key) == 0)
  165.         return HASH_OK;
  166.  
  167.     return HASH_NOT_FOUND;
  168. }
  169.  
  170. int
  171. hash_table_set_data (struct hash_table *table, char *key, void *data)
  172. {
  173.     struct bucket *bucket;
  174.     int hash;
  175.  
  176.     if (table == NULL || key == NULL || data == NULL)
  177.     return HASH_INVALID_PARAMETER;
  178.  
  179.     hash = hash_table_hash (key);
  180.  
  181.     for (bucket = table->table[hash]; bucket != NULL; bucket = bucket->next)
  182.     if (strcmp (bucket->key, key) == 0)
  183.     {
  184.         bucket->data = data;
  185.         return HASH_OK;
  186.     }
  187.  
  188.     return HASH_NOT_FOUND;
  189. }
  190.  
  191. void *
  192. hash_table_retrive_data (struct hash_table *table, char *key)
  193. {
  194.     struct bucket *bucket;
  195.     int hash;
  196.  
  197.     if (table == NULL || key == NULL)
  198.     return NULL;
  199.  
  200.     hash = hash_table_hash (key);
  201.  
  202.     for (bucket = table->table[hash]; bucket != NULL; bucket = bucket->next)
  203.     if (strcmp (bucket->key, key) == 0)
  204.         return bucket->data;
  205.  
  206.     return NULL;
  207. }
  208.  
  209. /* hash.c ends here */
  210.